package com.weilele.mvvm.utils.file

import android.content.Context
import android.content.SharedPreferences
import com.tencent.mmkv.MMKV
import com.weilele.mvvm.MvvmConf
import com.weilele.mvvm.app
import com.weilele.mvvm.gson
import com.weilele.mvvm.utils.printStackTrace

/**
 * 描述：SharedPreferences 工具集合
 */
var SP_FILE_NAME = ""
    get() {
        if (field == "") {
            field = app.packageName.replace(".", "_")
        }
        return field
    }

@Deprecated("推荐使用腾讯的MMKV库", ReplaceWith(""))
fun Context.getSp(): SharedPreferences {
    return getSharedPreferences(SP_FILE_NAME, Context.MODE_PRIVATE)
}

/**
 * 数据保存再sp，只支持sp支持的基本类型
 */
@Deprecated("推荐使用腾讯的MMKV库", ReplaceWith(""))
fun Context.spSet(keyName: String?, keyValue: Any?) {
    if (keyName == null || keyValue == null) {
        return
    }
    try {
        getEditor(keyName, keyValue).apply()
    } catch (e: Throwable) {
        printStackTrace { e }
    }
}

@Deprecated("推荐使用腾讯的MMKV库", ReplaceWith(""))
fun Context.spCommit(keyName: String?, keyValue: Any?): Boolean {
    if (keyName == null || keyValue == null) {
        return false
    }
    return try {
        getEditor(keyName, keyValue).commit()
    } catch (e: Throwable) {
        printStackTrace { e }
        false
    }
}

@Deprecated("推荐使用腾讯的MMKV库", ReplaceWith(""))
fun Context.spRemove(keyName: String) {
    getSp().edit().remove(keyName).apply()
}

private fun Context.getEditor(keyName: String?, keyValue: Any?) = getSp().edit().apply {
    when (keyValue) {
        is String -> {
            putString(keyName, keyValue)
        }
        is Boolean -> {
            putBoolean(keyName, keyValue)
        }
        is Int -> {
            putInt(keyName, keyValue)
        }
        is Float -> {
            putFloat(keyName, keyValue)
        }
        is Set<*> -> {
            putStringSet(keyName, keyValue as Set<String>)
        }
        is Long -> {
            putLong(keyName, keyValue)
        }
        else -> {
            putString(keyName, gson.toJson(keyValue))
        }
    }
}

/**
 * 从sp获取数据
 */
@Deprecated("推荐使用腾讯的MMKV库", ReplaceWith(""))
fun <T> Context.spGet(keyName: String, default: T): T {
    try {
        val result: Any?
        when (default) {
            is String -> {
                result = getSp().getString(keyName, default)
            }
            is Boolean -> {
                result = getSp().getBoolean(keyName, default)
            }
            is Float -> {
                result = getSp().getFloat(keyName, default)
            }
            is Int -> {
                result = getSp().getInt(keyName, default)
            }
            is Long -> {
                result = getSp().getLong(keyName, default)
            }
            is Set<*> -> {
                result = getSp().getStringSet(keyName, default as Set<String>)
            }
            else -> {
                result = gson.fromJson(getSp().getString(keyName, ""), default!!::class.java)
                    ?: default
            }
        }
        return result as T
    } catch (e: Throwable) {
        return default
    }
}

/**
 * -------------------------------------腾讯替代sp的库-----------------------------------------
 */
val kv by lazy {
    //    "MMKV--->".logI("mmkv root: $rootDir")
    MMKV.initialize(app)
    MMKV.defaultMMKV()
}

/**
 * 移除key
 */
fun mmkvRemoveKey(keyName: String) = kv.removeValueForKey(keyName)
fun mmkvRemoveKey(vararg keys: String) = kv.removeValuesForKeys(keys)

/**
 * 是否包含key
 */
fun mmkvContainsKey(keyName: String): Boolean = kv.containsKey(keyName)

/**
 * 保存数据
 */
fun mmkvPutValue(key: String, value: Any?) = kvEncode(key, value)

/**
 * 获取数据
 */
fun <T> mmkvGetValue(key: String, defaultValue: T) = kvDecode(key, defaultValue)

/**
 * 数据清除
 */
fun mmkvClearAll() = kv.clearAll()
fun mmkvClearMemoryCache() = kv.clearMemoryCache()

/**
 * 所有的key
 */
fun mmkvAllKeys() = kv.allKeys()

/**
 * 保存数据
 */
fun kvEncode(keyName: String, keyValue: Any?): Boolean {
    if (keyValue == null) {
        if (mmkvContainsKey(keyName)) {
            mmkvRemoveKey(keyName)
        }
        return true
    }
    return when (keyValue) {
        is String -> {
            kv.encode(keyName, keyValue)
        }
        is Boolean -> {
            kv.encode(keyName, keyValue)
        }
        is Int -> {
            kv.encode(keyName, keyValue)
        }
        is Float -> {
            kv.encode(keyName, keyValue)
        }
        is Set<*> -> {
            kv.encode(keyName, keyValue as Set<String>)
        }
        is Long -> {
            kv.encode(keyName, keyValue)
        }
        is Double -> {
            kv.encode(keyName, keyValue)
        }
        is ByteArray -> {
            kv.encode(keyName, keyValue)
        }
        else -> {
            kv.encode(keyName, gson.toJson(keyValue))
        }
    }
}

/**
 * 解析数据
 */
fun <T> kvDecode(keyName: String, default: T): T {
    if (!mmkvContainsKey(keyName)) {
        return default
    }
    @Suppress("IMPLICIT_CAST_TO_ANY")
    val result = when (default) {
        is String -> {
            kv.decodeString(keyName, default)
        }
        is Boolean -> {
            kv.decodeBool(keyName, default)
        }
        is Int -> {
            kv.decodeInt(keyName, default)
        }
        is Float -> {
            kv.decodeFloat(keyName, default)
        }
        is Set<*> -> {
            kv.decodeStringSet(keyName, default as Set<String>)
        }
        is Long -> {
            kv.decodeLong(keyName, default)
        }
        is Double -> {
            kv.decodeDouble(keyName, default)
        }
        is ByteArray -> {
            kv.decodeBytes(keyName, default)
        }
        else -> {
            val json = kv.decodeString(keyName, null)
            if (json == null) {
                default
            } else {
                gson.fromJson(json, default!!::class.java) ?: default
            }
        }
    }
    return result as T
}


